﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace isky.Plugin
{

    /**
     * 把表示美元的阿拉伯数字转换为英文大写的格式。
     * 
     * @author Ken
     * 
     */
    public class DollarsNumberFormat
    {
       
        private static  string[] MAJORS = { " ", " Thousand ", " Million ",
			" Billion ", " Trillion ", " Quadrillion ", " Quintillion " };

        private static string[] TENS = { " ", " Ten ", " Twenty ", " Thirty ",
            " Forty ", " Fifty ", " Sixty ", " Seventy ", " Eighty ",
            " Ninety " };

        private static string[] NUMBERS = { " ", " One ", " Two ", " Three ",
            " Four ", " Five ", " Six ", " Seven ", " Eight ", " Nine ",
            " Ten ", " Eleven ", " Twelve ", " Thirteen ", " Fourteen ",
            " Fifteen ", " Sixteen ", " Seventeen ", " Eighteen ", " Nineteen " };

        /**
         * 把阿拉伯数字转换为英文大写格式。<br>
         * 例如：123.01：One Hundred Twenty Three Dollars And One Cent
         * 
         * @param value
         * @return
         */
        public string format(double value)
        {
            double number = Math.Round(value, 2);// 小数点保留两位
            string result = getDollarPart(number) + getCentPart(number);
            return result.Replace("  ", " ").ToUpper();// 去掉多余的空格，并转为大写
        }

        // 获取整数部分的转换
        private string getDollarPart(double value)
        {
            int number = (int)value;
            string dollars = formatDigit(number);
            if (dollars.Trim().Equals(""))
                return "No Dollars";
            else if (dollars.Trim().Equals("One"))
                return "One Dollar";
            else
                return dollars + " Dollars";

        }

        // 获取小数部分的转换
        private string getCentPart(double number)
        {
            int cents = (int)(Math.Round(number * 100) - ((int)number) * 100);
            string centsPart = formatDigit(cents);

            if (centsPart.Trim().Equals(""))
                return " And No Cents";
            else if (centsPart.Trim().Equals("One"))
                return " And One Cent";
            else
                return " And " + centsPart + " Cents";
        }

        private string formatDigit(int value)
        {
            int number = value;
            string prefix = ""; // 正负号前缀。

            if (number < 0)
            {
                number = -number;
                prefix = "Negative ";
            }

            string result = "";
            int index = 0;
            do
            {
                int n = number % 1000;
                if (n != 0)
                {
                    result = formatLessThanOneThousand(n) + MAJORS[index] + result;
                }
                index++;
                number /= 1000;
            } while (number > 0);

            return (prefix + result).Trim();
        }

        private string formatLessThanOneThousand(int value)
        {
            int number = value;
            string result = "";
            if (number % 100 < 20)
            {// 前两位数的值在20以内。
                result = NUMBERS[number % 100];
                number /= 100;
            }
            else
            {// 前两位数的值在20以外。
                result = NUMBERS[number % 10];// 个位
                number /= 10;

                result = TENS[number % 10] + result;// 十位&个位
                number /= 10;
            }
            if (number == 0)
                return result;
            else
                return NUMBERS[number] + " Hundred " + result; // 百位&十位&个位。
        }

        //public static void main(String[] args)
        //{
        //    DollarsNumberFormat f = new DollarsNumberFormat();
        //    System.out.println("123456789 = " + f.format(123456789));
        //    System.out.println("123.01 = " + f.format(123.01));
        //    System.out.println("0.01 = " + f.format(0.01));
        //    System.out.println("0.0 = " + f.format(0.0));
        //    System.out.println("-123.71 = " + f.format(-123.71));

        //}
    }
}
